package com.example.s3demo.utils

import java.io.*
import java.nio.file.Files
import java.nio.file.attribute.BasicFileAttributes
import java.text.SimpleDateFormat
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.*

object FileUtil {
    fun delete(fileName: String): Boolean {
        val file = File(fileName)
        return if (!file.exists()) {
            //System.out.println("删除文件失败:" + fileName +"不存在！");
            false
        } else {
            if (file.isFile) deleteFile(fileName)
            else deleteDirectory(fileName)
        }
    }

    fun deleteFile(fileName: String?): Boolean {
        val file = File(fileName)
        return if (file.exists() && file.isFile) {
            if (file.delete()) {
                true
            } else {
                false
            }
        } else {
            false
        }
    }

    fun deleteDirectory(dir: String): Boolean {
        var dir = dir
        if (!dir.endsWith("/")) dir = "$dir/"
        val dirFile = File(dir)
        if ((!dirFile.exists()) || (!dirFile.isDirectory)) {
            return false
        }
        var flag = true
        val files = dirFile.listFiles()
        for (i in files.indices) {
            if (files[i].isFile) {
                flag = deleteFile(files[i].absolutePath)
                if (!flag) break
            } else if (files[i].isDirectory) {
                flag = deleteDirectory(files[i].absolutePath)
                if (!flag) break
            }
        }
        if (!flag) {
            return false
        }
        return if (dirFile.delete()) {
            true
        } else {
            false
        }
    }

    fun getCreationTime(file: File?): String? {
        if (file == null) {
            return null
        }
        var attr: BasicFileAttributes? = null
        try {
            val path = file.toPath()
            attr = Files.readAttributes(path, BasicFileAttributes::class.java)
        } catch (e: IOException) {
            e.printStackTrace()
        }
        val instant = attr!!.creationTime().toInstant()
        val format =
            DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withZone(ZoneId.systemDefault()).format(instant)
        return format
    }

    fun getLastModifyTime(file: File?): String? {
        if (file == null) {
            return null
        }
        var attr: BasicFileAttributes? = null
        try {
            val path = file.toPath()
            attr = Files.readAttributes(path, BasicFileAttributes::class.java)
        } catch (e: IOException) {
            e.printStackTrace()
        }
        val instant = attr!!.lastModifiedTime().toInstant()
        val format =
            DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withZone(ZoneId.systemDefault()).format(instant)
        return format
    }

    fun getLastModifyTimeGMT(file: File?): String? {
        if (file == null) {
            return null
        }
        val modifiedTime = Date(file.lastModified())
        val dateFormat = SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.US)
        dateFormat.timeZone = TimeZone.getTimeZone("GMT")
        val time = dateFormat.format(modifiedTime)
        return time
    }

    fun getFileSize(file: File?): Long {
        if (file == null) {
            return 0
        }
        var attr: BasicFileAttributes? = null
        try {
            val path = file.toPath()
            attr = Files.readAttributes(path, BasicFileAttributes::class.java)
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return attr!!.size()
    }

    fun saveFile(filePath: String?, fileStream: InputStream) {
        var out: FileOutputStream? = null
        try {
            out = FileOutputStream(filePath)
            val file = convertStreamToByte(fileStream)
            out.write(file)
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            if (out != null) {
                try {
                    out.flush()
                    out.close()
                } catch (ex: Exception) {
                }
            }
        }
    }

    fun saveFile(filePath: String?, data: ByteArray?) {
        var out: FileOutputStream? = null
        try {
            out = FileOutputStream(filePath)
            out.write(data)
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            if (out != null) {
                try {
                    out.flush()
                    out.close()
                } catch (ex: Exception) {
                }
            }
        }
    }

    fun getFile(filePath: String?): ByteArray? {
        var buffer: ByteArray? = null
        try {
            val file = File(filePath)
            val fis = FileInputStream(file)
            val bos = ByteArrayOutputStream(1000)
            val b = ByteArray(1000)
            var n: Int
            while ((fis.read(b).also { n = it }) != -1) {
                bos.write(b, 0, n)
            }
            fis.close()
            bos.close()
            buffer = bos.toByteArray()
        } catch (e: FileNotFoundException) {
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return buffer
    }

    @Throws(IOException::class)
    fun convertStreamToByte(inputStream: InputStream): ByteArray {
        val buffer = ByteArray(1024)
        var len = 0
        val bos = ByteArrayOutputStream()
        while ((inputStream.read(buffer).also { len = it }) != -1) {
            bos.write(buffer, 0, len)
        }
        bos.close()
        return bos.toByteArray()
    }

    fun getContentType(fileName: String): String {
        var contentType = "application/octet-stream"
        val fileNameList = fileName.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
        if (fileNameList.size == 1) {
            return contentType
        }
        var fileExt = fileNameList[fileNameList.size - 1]
        if (fileExt != null) {
            fileExt = fileExt.lowercase(Locale.getDefault())
            when (fileExt) {
                "txt" -> contentType = "text/plain"
                "html", "htm" -> contentType = "text/html"
                "css" -> contentType = "text/css"
                "js" -> contentType = "application/javascript"
                "json" -> contentType = "application/json"
                "xml" -> contentType = "application/xml"
                "jpg", "jpeg" -> contentType = "image/jpeg"
                "gif" -> contentType = "image/gif"
                "png" -> contentType = "image/png"
                "svg" -> contentType = "image/svg+xml"
                "mp3" -> contentType = "audio/mpeg"
                "mp4" -> contentType = "video/mp4"
                "avi" -> contentType = "video/avi"
                "mov" -> contentType = "video/quicktime"
                "doc", "docx" -> contentType = "application/msword"
                "xls", "xlsx" -> contentType = "application/vnd.ms-excel"
                "ppt", "pptx" -> contentType = "application/vnd.ms-powerpoint"
                "rar" -> contentType = "application/x-rar-compressed"
                "zip" -> contentType = "application/zip"
                "tar" -> contentType = "application/x-tar"
                "gz" -> contentType = "application/x-gzip"
            }
        }
        return contentType
    }

    fun writeFile(fileName: String?, content: String) {
        var fos: FileOutputStream? = null
        try {
            fos = FileOutputStream(fileName)
            fos.write(content.toByteArray(charset("UTF-8")))
            fos.close()
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            try {
                fos?.close()
            } catch (e: Exception) {
            }
        }
    }

    fun readFileContent(fileName: String?): String? {
        var fileContent: String? = ""
        var fis: FileInputStream? = null
        var isr: InputStreamReader? = null
        try {
            fis = FileInputStream(fileName)
            isr = InputStreamReader(fis, "UTF-8")
            val br = BufferedReader(isr)
            var line: String? = null
            while ((br.readLine().also { line = it }) != null) {
                fileContent += line
            }
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            try {
                isr?.close()
                fis?.close()
            } catch (e: Exception) {
            }
        }
        return fileContent
    }

    @Throws(IOException::class)
    fun copyFile(sourceFilePath: String?, tagretFilePath: String?) {
        try {
            val file = File(tagretFilePath)
            if (file.exists()) {
                file.delete()
            }
            val `in`: InputStream = FileInputStream(sourceFilePath)
            val out: OutputStream = FileOutputStream(tagretFilePath)
            val buffer = ByteArray(2048)
            var nBytes = 0
            while ((`in`.read(buffer).also { nBytes = it }) > 0) {
                out.write(buffer, 0, nBytes)
            }
            out.flush()
            out.close()
            `in`.close()
        } catch (e: FileNotFoundException) {
            e.printStackTrace()
        }
    }
}
